#include <iostream>
#include <map>
#include <cstdlib>
#include <regex>
#include "yaml-cpp/yaml.h"

void parseYaml(){
  YAML::Node config = YAML::LoadFile("../assets/config.yaml");
  std::string scheme_name = "icc_logsim";
  std::string package_type = "rosbag";
  std::map<std::string, int> channel_frame_rates;
  if (channel_frame_rates.empty()) {
    std::cout << "目前是空的" << std::endl;
  }
  if (config.IsMap()) {
    std::cout << "version:" << config["version"].as<std::string>() << std::endl;
    YAML::Node schemes = config["scheme"];
    if (schemes.IsSequence()) {
      for(size_t i = 0; i < schemes.size(); ++i) {
        std::cout << "name:" << schemes[i]["name"].as<std::string>() << std::endl;
        if (scheme_name == schemes[i]["name"].as<std::string>() && schemes[i]["switch"].as<std::string>() == "on") {
          YAML::Node kinds = schemes[i]["kinds"];
          if (kinds.IsSequence()) {
            std::cout << "kinds: " << std::endl;
            for(size_t j = 0; j < kinds.size(); ++j) {
              if (kinds[j]["package_type"].as<std::string>() == package_type && kinds[j]["switch"].as<std::string>() == "on") {
                std::cout << "package_type:" << kinds[j]["package_type"].as<std::string>() << std::endl;
                YAML::Node channels = kinds[j]["channels"];
                if (channels.IsSequence()) {
                  for(size_t k = 0; k < channels.size(); k++) {
                    std::string channel_name = channels[k]["name"].as<std::string>();
                    channel_frame_rates[channel_name] = channels[k]["standard_value"].as<int>();
                    if (channels[k]["threshold"].IsSequence()) {
                      channel_frame_rates[channel_name + "_min"] = channels[k]["threshold"][0].as<int>();
                      channel_frame_rates[channel_name + "_max"] = channels[k]["threshold"][1].as<int>();
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  for (std::map<std::string, int>::iterator it = channel_frame_rates.begin(); it != channel_frame_rates.end(); it++) {
    std::cout << "map: " << it->first << ": " << it->second << std::endl;
  }
}


std::vector<std::string> split(const std::string& str, const std::string& delim) {
  std::vector<std::string> res;
  if("" == str) return res;
  //先将要切割的字符串从string类型转换为char*类型
  char * strs = new char[str.length() + 1] ; //不要忘了
  strcpy(strs, str.c_str());

  char * d = new char[delim.length() + 1];
  strcpy(d, delim.c_str());

  char *p = strtok(strs, d);
  while(p) {
    std::string s = p; //分割得到的字符串转换为string类型
    res.push_back(s); //存入结果数组
    p = strtok(NULL, d);
  }

  return res;
}


std::map<std::string, int> parseRosbagOrRecordInfo(const std::string& bag_path, const std::string& bag_type) {
  const std::string cmd = "cat " + bag_path;
  FILE *fp;
  fp = popen(cmd.c_str(), "r");
  std::map<std::string, int> channel_frame_rates;
  if (fp == NULL) {
    std::cout << "------ failed to execute " << cmd;
  } else {
    bool flag = false;
    //按行读取
    char content[1024];
    int duration = 0; //单位秒
    while (fgets(content, sizeof(content) - 1, fp) != NULL) {
      std::vector<std::string> infos = split(std::string(content), " ");
      if (infos.at(0) == "duration:"){
        if (bag_type == "rosbag") {
          std::regex reg("\\(([0-9]*)s\\)");
          std::cmatch m;
          auto ret = std::regex_search(content, m, reg);
          if (ret && m.size() > 1) {
            duration = std::stoi(m[1].str());
          }
          std::cout << content << std::endl;
        } else if (bag_type == "record"){
          duration = std::stoi(infos.at(1));
        }
      } else if (infos.at(0) == "topics:" || infos.at(0) == "channel_info:\n") {
        std::cout << content << std::endl;
        flag = true;
        if (duration > 0 && bag_type == "rosbag") {
          channel_frame_rates[infos.at(1)] = std::stod(infos.at(2)) / (double)duration;
        }
      } else if (flag && duration > 0) {
        channel_frame_rates[infos.at(0)] = std::stod(infos.at(1)) / (double)duration;
      }
    }
    for (std::map<std::string, int>::iterator it = channel_frame_rates.begin(); it != channel_frame_rates.end(); it++) {
      std::cout << "map: " << it->first << ": " << it->second << std::endl;
    }
  }
  pclose(fp);
  return channel_frame_rates;
}


void testReg() {
  std::regex reg("\\(([0-9]*)s\\)");
  std::cmatch m;
  auto ret = std::regex_search("duration:    1:09s (69s)", m, reg);
  if (ret)
  {
      std::cout << m[1].str() << std::endl;
  }

  std::cout << "prefix:" << m.prefix() << std::endl;
  std::cout << "suffix:" << m.suffix() << std::endl;
}


bool compare_pred(unsigned char a, unsigned char b) {
  return std::tolower(a) == std::tolower(b);
}
bool EndsWith(const std::string& str, const std::string& suffix) {

  if (str.size() < suffix.size()) {
    return false;
  }

  std::string tstr = str.substr(str.size() - suffix.size());

  if (tstr.length() == suffix.length()) {
    return std::equal(suffix.begin(), suffix.end(), tstr.begin(), compare_pred);
  } else {
    return false;
  }
}
int main()
{
  std::string bag_path("../assets/bagInfo.txt");
  std::string record_path("../assets/recordInfo.txt");
  parseRosbagOrRecordInfo(bag_path, "rosbag");
  parseRosbagOrRecordInfo(record_path, "record");
  parseYaml();
  return 0;
}
